
#include "bsp_uart.h"

/* 以下几个全局变量仅用于测试*/

volatile uint8_t u8TxData[2] = {0xaa,0x55};
volatile uint8_t u8RxData[2] = {0x00};

uint8_t u8TxCnt=0,u8RxCnt=0;

//串口模块配置
// PA9 -- UART0_TX 
// PA10 -- UART0_RX 
void BSP_Uart0_Config(void)
{
	stc_uart_cfg_t  stcCfg;	
    stc_uart_baud_t stcBaud;
	stc_gpio_cfg_t stcGpioCfg;
    
	DDL_ZERO_STRUCT(stcCfg);
    DDL_ZERO_STRUCT(stcBaud);
    DDL_ZERO_STRUCT(stcGpioCfg); 
	 
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///<使能GPIO外设时钟门控开关
    
    stcGpioCfg.enDir = GpioDirOut;

	Gpio_Init(GpioPortA,GpioPin9,&stcGpioCfg);
	Gpio_SetAfMode(GpioPortA,GpioPin9,GpioAf1); //配置PA9 为UART0 TX

	stcGpioCfg.enDir = GpioDirIn;
	Gpio_Init(GpioPortA,GpioPin10,&stcGpioCfg);
	Gpio_SetAfMode(GpioPortA,GpioPin10,GpioAf1);//配置PA10 为UART0 RX
    
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE); ///<使能UART0外设时钟门控开关
    
    ///<UART Init
    stcCfg.enRunMode        = UartMskMode1;                 ///<模式1
    stcCfg.enStopBit        = UartMsk1bit;                  ///<1bit停止位

    stcCfg.enMmdorCk        = UartMskNone;            		///<无校验位
    stcCfg.stcBaud.u32Baud  = 9600;                       ///<波特率 9600无误差,115200 误差0.16%
                     
    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;              ///<通道采样分频配置
    stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();        ///</<获得外设时钟（PCLK）频率值
    Uart_Init(M0P_UART0, &stcCfg);                          ///<串口初始化
    
	///<UART中断使能
    Uart_EnableIrq(M0P_UART0,UartRxIrq); //使能串口接收中断
	//Uart_EnableIrq(M0P_UART0,UartTxIrq); //使能串口发送中断
	
	///<系统中断使能
    EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE);    
	
	Uart_ClrStatus(M0P_UART0,UartRC);    //清接收请求
    Uart_ClrStatus(M0P_UART0,UartTC);    //清发送请求
}

//串口模块配置(EVB-board 端口未占用,用于打印调试)
// PA2 -- UART1_TX
// PA3 -- UART1_RX
void BSP_Uart1_Config(void)
{
	stc_uart_cfg_t  stcCfg;	
    stc_uart_baud_t stcBaud;
	stc_gpio_cfg_t stcGpioCfg;
    
	DDL_ZERO_STRUCT(stcCfg);
    DDL_ZERO_STRUCT(stcBaud);
    DDL_ZERO_STRUCT(stcGpioCfg); 
	 
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///<使能GPIO外设时钟门控开关
    
    stcGpioCfg.enDir = GpioDirOut;
    Gpio_Init(GpioPortA,GpioPin2,&stcGpioCfg);
    Gpio_SetAfMode(GpioPortA,GpioPin2,GpioAf1); //配置PA2 为UART1 TX
	
    stcGpioCfg.enDir = GpioDirIn;
    Gpio_Init(GpioPortA,GpioPin3,&stcGpioCfg);
    Gpio_SetAfMode(GpioPortA,GpioPin3,GpioAf1);//配置PA3 为UART1 RX
	    
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart1,TRUE); ///<使能UART1外设时钟门控开关
    
    ///<UART Init
    stcCfg.enRunMode        = UartMskMode1;                 ///<模式1
    stcCfg.enStopBit        = UartMsk1bit;                  ///<1bit停止位

    stcCfg.enMmdorCk        = UartMskNone;            		///<无校验位
    stcCfg.stcBaud.u32Baud  = 115200;                       ///<波特率 9600 无误差,115200 误差0.16%
                     
    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;              ///<通道采样分频配置
    stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();        ///</<获得外设时钟（PCLK）频率值
    Uart_Init(M0P_UART1, &stcCfg);                          ///<串口初始化
    
	///<UART中断使能
    Uart_EnableIrq(M0P_UART1,UartRxIrq); //使能串口接收中断
	//Uart_EnableIrq(M0P_UART1,UartTxIrq); //使能串口发送中断
	
	///<系统中断使能
    EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE);    
	
	Uart_ClrStatus(M0P_UART1,UartRC);    //清接收请求
    Uart_ClrStatus(M0P_UART1,UartTC);    //清发送请求
}


//串口模块配置
void BSP_Uart2_Config(void)
{
    stc_uart_cfg_t  stcCfg;	
    stc_uart_baud_t stcBaud;
	stc_gpio_cfg_t stcGpioCfg;
    
	DDL_ZERO_STRUCT(stcCfg);
    DDL_ZERO_STRUCT(stcBaud);
    DDL_ZERO_STRUCT(stcGpioCfg); 
	 
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///<使能GPIO外设时钟门控开关
    
    stcGpioCfg.enDir = GpioDirOut;
    Gpio_Init(GpioPortC,GpioPin3,&stcGpioCfg);
    Gpio_SetAfMode(GpioPortC,GpioPin3,GpioAf5); //配置PC03 为UART2 TX
    stcGpioCfg.enDir = GpioDirIn;
    Gpio_Init(GpioPortC,GpioPin2,&stcGpioCfg);
    Gpio_SetAfMode(GpioPortC,GpioPin2,GpioAf4);//配置PC02 为UART2 RX
	    
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart2,TRUE); ///<使能UART2外设时钟门控开关
    
    ///<UART Init
    stcCfg.enRunMode        = UartMskMode1;                 ///<模式1
    stcCfg.enStopBit        = UartMsk1bit;                  ///<1bit停止位

    stcCfg.enMmdorCk        = UartMskNone;            		///<无校验位
    stcCfg.stcBaud.u32Baud  = 115200;                       ///<波特率 9600 无误差,115200 误差0.16%
                     
    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;              ///<通道采样分频配置
    stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();        ///</<获得外设时钟（PCLK）频率值
    Uart_Init(M0P_UART2, &stcCfg);                          ///<串口初始化
    
	///<UART中断使能
    Uart_EnableIrq(M0P_UART2,UartRxIrq); //使能串口接收中断
	//Uart_EnableIrq(M0P_UART2,UartTxIrq); //使能串口发送中断
	
	///<系统中断使能
    EnableNvic(UART0_2_IRQn, IrqLevel2, TRUE);    
	
	Uart_ClrStatus(M0P_UART2,UartRC);    //清接收请求
    Uart_ClrStatus(M0P_UART2,UartTC);    //清发送请求
	
}


void Uart2_IRQHandler(void)
{
    if(Uart_GetStatus(M0P_UART2, UartRC))
    {
        Uart_ClrStatus(M0P_UART2, UartRC);              //清除接收中断状态位
	}
}


void Uart0_IRQHandler(void)
{
    if(Uart_GetStatus(M0P_UART0, UartRC))
    {
        Uart_ClrStatus(M0P_UART0, UartRC);              //清除接收中断状态位
		
        //u8RxData[u8RxCnt] = Uart_ReceiveData(M0P_UART0);  	
        //u8RxCnt++;
//        if(u8RxCnt>1)                                   //如果已接收两个字节
//        {
//            Uart_DisableIrq(M0P_UART1,UartRxIrq);       //禁止接收中断
 //       }	
    }
    
    if(Uart_GetStatus(M0P_UART0, UartTC))
    {
        Uart_ClrStatus(M0P_UART0, UartTC);              //清除发送中断状态位
//        Uart_SendDataIt(M0P_UART1, u8TxData[u8TxCnt++]);//发送数据
//        if(u8TxCnt>1)                                   //如果已发送两个字节
 //       {
//            u8TxCnt = 0;
//            u8RxCnt = 0;
//           Uart_DisableIrq(M0P_UART1,UartTxIrq);       //禁止发送中断
//            Uart_EnableIrq(M0P_UART1,UartRxIrq);        //使能接收中断
//        } 
    }
}

// how to use:    Uart_SendDataIt(M0P_UART1, ~u8RxData); Uart_SendDataPoll(M0P_UART0, 0x16);     



/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
#if defined ( __CC_ARM )

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)        
  /*
 * Arm Compiler above 6.10.1 (armclang)
 */
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
  
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
	
/*
 * GNU Compiler
 */
#elif defined ( __GNUC__ )

/* With GCC, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)

#endif


PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART1 and Loop until the end of transmission */
  Uart_SendDataPoll(M0P_UART0, (uint8_t)ch);
  return ch;
}


GETCHAR_PROTOTYPE
{
    int ret;      
	ret = Uart_ReceiveData(M0P_UART0);
    return ret;
}


